package com.wx.rpc.service.core;

import com.wx.rpc.service.annotation.RpcAnnotation;
import com.wx.rpc.service.handler.ProcessorHandler;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author wx
 * @Description: rpc服务
 * @date 2019/3/8 000815:51
 */
public class RPCServer {
    /**
     * 可缓存线程池 如果有空闲线程则会去复用，如果没有则创建新线程，没有数量限制
     */
    private final ExecutorService executorService = Executors.newCachedThreadPool();

    /**
     * 注册中心
     */
    private IRegisterService registerService;

    /**
     * 服务发布地址
     */
    private String serviceAddress;

    Map<String, Object> handlerMap = new HashMap<String, Object>();

    public RPCServer(IRegisterService registerService, String serviceAddress) {
        this.registerService = registerService;
        this.serviceAddress = serviceAddress;
    }


    /**
     * @description: 注解信息获取服务名称，服务版本号并绑定服务
     * @author: wx
     * @date: 2019/3/8 0008
     * @param services
     * @return: void
     */
    public void bind(Object ... services) {
        for (Object service : services) {
            RpcAnnotation annotation = service.getClass().getAnnotation(RpcAnnotation.class);
            String serviceName = annotation.value().getName();
            String version = annotation.version();
            if (StringUtils.isBlank(serviceName)){
                return;
            }
            if (StringUtils.isNotBlank(version)) {
                serviceName = serviceName + "-" + version;
            }
            // 绑定服务接口名称对应的服务
            handlerMap.put(serviceName, service);
        }
    }
    
    /**
     * @description: 发布服务端服务
     * @author: wx
     * @date: 2019/3/8 0008
     * @param 
     * @return: void
     */
    public void publishServer(){
        ServerSocket serverSocket = null;
        try {
            // 服务端启动服务代码内容==================
            // 启动服务
            serverSocket = new ServerSocket(Integer.valueOf(serviceAddress.split(":", -1)[1]));
            for (String interfaceName : handlerMap.keySet()) {
                registerService.register(interfaceName, serviceAddress);
                System.out.println("注册服务成功, interfaceName : " + interfaceName + ", serviceAddress : " + serviceAddress);
            }

            // 服务端获取客户端请求代码处理======================
            // 获取监听
            //todo 使用netty代替
            while (true) {
                Socket socket = serverSocket.accept();
                executorService.execute(new ProcessorHandler(socket, handlerMap));
             }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != serverSocket) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}
